﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Folder.cs" company="Anton Frattaroli">
//   Copyright (c) Anton Frattaroli. All rights reserved.
// </copyright>
// <summary>
//   Defines the Folder class.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Lidocaine.Data
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Globalization;
    using Lidocaine.BusinessObjects;
    
    /// <summary>
    /// Defines the Folder class.
    /// </summary>
    public static class Folder
    {
        /// <summary>
        /// Initializes a new instance of the Folder class.
        /// </summary>
        /// <param name="folderId">The identity of the database table's row referencing this folder.</param>
        /// <returns>An instantiated Folder.</returns>
        public static BusinessObjects.Folder Select(int folderId)
        {
            BusinessObjects.Folder folder = null;
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetFolderByID", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FolderID", folderId);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            rdr.Read();
                            folder = new BusinessObjects.Folder();
                            folder.Id = folderId;
                            folder.Path = rdr["FolderPath"].ToString();
                        }
                    }
                }
            }

            return folder;
        }

        /// <summary>
        /// Finds a folder based on its path, if it exists.
        /// </summary>
        /// <param name="path">The virtual path to search for.</param>
        /// <returns>If the folder is found, a folder is populated and returned. Returns null otherwise.</returns>
        public static BusinessObjects.Folder Select(string path)
        {
            BusinessObjects.Folder folder = null;
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetFolderIDFromFolderPath", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FolderPath", path);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            rdr.Read();
                            folder = new BusinessObjects.Folder();
                            folder.Id = Convert.ToInt32(rdr["FolderID"], CultureInfo.InvariantCulture);
                            folder.Path = path;
                        }
                    }
                }
            }

            return folder;
        }

        public static List<Permission> GetPermissionsWithRoleInfo(string path)
        {
            Permission permission = null;
            List<Permission> permissions = new List<Permission>();
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetFolderPermissionsWithRoleInfo", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FolderPath", path);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            while (rdr.Read())
                            {
                                permission = new Permission();
                                permission.Id = Convert.ToInt32(rdr["PermissionID"], CultureInfo.InvariantCulture);
                                permission.AllowType = rdr["PermissionAllowType"].ToString() == "True" ? PermissionAllowType.Role : PermissionAllowType.UserProfile;
                                permission.AllowId = Convert.ToInt32(rdr["PermissionAllowID"], CultureInfo.InvariantCulture);
                                permission.IsActiveDirectoryRole = rdr["ActiveDirectory"] == DBNull.Value ? false : rdr["ActiveDirectory"].ToString() == "True" ? true : false;
                                permission.Name = rdr["RoleName"] != DBNull.Value ? rdr["RoleName"].ToString() : rdr["UserName"] != DBNull.Value ? rdr["UserName"].ToString() : string.Empty;
                                permissions.Add(permission);
                            }
                        }
                    }
                }
            }

            return permissions;
        }

        /// <summary>
        /// Inserts the Folder object into the database.
        /// </summary>
        /// <param name="folder">The Folder to insert.</param>
        /// <returns>The inserted Folder with a newly populated Id field.</returns>
        public static BusinessObjects.Folder Insert(BusinessObjects.Folder folder)
        {
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.InsertFolder", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FolderPath", folder.Path);
                    folder.Id = Convert.ToInt32(cmd.ExecuteScalar(), CultureInfo.InvariantCulture);
                }
            }

            return folder;
        }

        /// <summary>
        /// Updates the Folder's database fields.
        /// </summary>
        /// <param name="folder">The Folder to update.</param>
        public static void Update(BusinessObjects.Folder folder)
        {
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.UpdateFolder", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FolderID", folder.Id);
                    cmd.Parameters.AddWithValue("@FolderPath", folder.Path);
                    cmd.ExecuteNonQuery();
                }
            }
        }

        /// <summary>
        /// Deletes the Folder's database entry.
        /// </summary>
        /// <param name="folder">The Folder to delete.</param>
        /// <returns>A list of file paths to delete.</returns>
        public static List<string> Delete(BusinessObjects.Folder folder)
        {
            List<string> files = new List<string>();
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.DeletePagesByFolderPath", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FolderPath", folder.Path + "/%");
                    cmd.ExecuteNonQuery();
                }

                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetFilePathByFolderPath", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FolderPath", folder.Path + "/%");
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            while (rdr.Read())
                            {
                                files.Add(rdr["FilePath"].ToString());
                            }
                        }
                    }
                }

                for (int i = 0; i < files.Count; i++)
                {
                    using (SqlCommand cmd = new SqlCommand("Lidocaine.DeleteFileByFilePath", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@FilePath", files[i]);
                        cmd.ExecuteNonQuery();
                    }
                }

                using (SqlCommand cmd = new SqlCommand("Lidocaine.DeleteFolder", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FolderPath", folder.Path);
                    cmd.ExecuteNonQuery();
                }
            }

            return files;
        }
    }
}